package com.gzsxy.esjy.common.base.util;

import com.alibaba.fastjson.JSON;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 */
public class HttpClient {

    private final static Logger log = LoggerFactory.getLogger(HttpClient.class);

    private final static Pattern ENV_FORMAT = Pattern.compile("\\$\\{[0-9a-zA-Z.\\-_]+\\}");

    private final static CloseableHttpClient http = HttpClients.custom()
            .setDefaultRequestConfig(RequestConfig.custom()
                    .setConnectTimeout(60 * 1000).setConnectionRequestTimeout(60 * 1000)
                    .setSocketTimeout(60 * 1000).build()).build();

    private static Environment env ;

    public HttpClient(Environment env) {
        HttpClient.env = env;
    }


    /**
     * 静态方法
     *
     * @param uri
     * @return
     */
    public static Method instance(String uri) {
        return new Method(http, getUrl(uri));
    }

    /**
     * bean
     *
     * @param url
     * @return
     */
    public Method url(String url) {
        return new Method(http, getUrl(url));
    }

    private static String getUrl(String url){
        Matcher matcher = ENV_FORMAT.matcher(url);
        while(matcher.find()){
            String group = matcher.group();
            String property = env.getProperty(group.substring(2,group.length()-1));
            if(property == null){
                throw new IllegalArgumentException(group+"没有设置值") ;
            }
            url = url.replace(group,property) ;
        }
        return url ;
    }



    public static class Method {

        private final CloseableHttpClient mHttp;

        private final String uri;

        private final Map<String,String> header = new HashMap<>() ;

        public Method(CloseableHttpClient http, String uri) {
            this.mHttp = http;
            this.uri = uri;
        }

        /**
         * 新增头部
         * @param name
         * @param value
         * @return
         */
        public Method addHeader(String name,String value){
            header.put(name,value) ;
            return this ;
        }

        public Method addHeader(Map<String,String> headers){
            header.putAll(headers);
            return this ;
        }

        /**
         * post json数据
         *
         * @param jsonObject
         * @return
         */
        public Result postJson(Object jsonObject) {
            HttpPost post = new HttpPost(uri);
            String request = null;
            if (!(jsonObject instanceof String)) {
                request = JSON.toJSONString(jsonObject);
            } else {
                request = (String) jsonObject;
            }
            post.addHeader("Content-type", "application/json; charset=utf-8");
            post.setHeader("Accept", "application/json");
            resetHeader(post) ;
            post.setEntity(new StringEntity(request, Charset.forName("UTF-8")));
            log.info("设置参数 json={}",request);
            return new Result(mHttp, post);
        }

        /**
         * 通过Post请求携带请求传参ueryOne?cardNo=599&userId=00000
         * @param pairs
         * @return
         * @throws Exception
         */
        public Result postFrom(List<NameValuePair> pairs)  {
            try {
                URIBuilder uriBuilder = new URIBuilder(uri);
                uriBuilder.addParameters(pairs);
                HttpPost post = new HttpPost(uriBuilder.build());
                resetHeader(post) ;
                return new Result(mHttp, post);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }



//        public Result postFrom(String box,String hardware) throws Exception {
//            HttpPost post = new HttpPost(uri);
//            //创建List集合，封装表单请求参数
//            List<NameValuePair> pairs=new ArrayList<>();
//            pairs.add(new BasicNameValuePair("box",box));//BasicNameValuePair放入键值对
//            pairs.add(new BasicNameValuePair("hardware",box));//BasicNameValuePair放入键值对
//            //创建表单的Entity对象
//            UrlEncodedFormEntity formEntity=null;
//
//                //参数1是封装好的表单数据，参数二是编码格式
//            post.addHeader("Content-type", "application/json; charset=utf-8");
//            post.setHeader("Authorization", "Bearer67bdcb46-3469-4eb6-9ca2-6077935c6634");
//            formEntity=new UrlEncodedFormEntity(pairs,"UTF-8"); //使UTF-8封装
//            post.setEntity(formEntity);
//            return new Result(mHttp, post);
//        }

        /**
         * 文件上传
         * @param fileParamName
         * @param base64
         * @param otherText
         * @return
         */
        public Result postMultipart(String fileParamName,String fileName,String base64,Map<String,Object> otherText){
            HttpPost post = new HttpPost(uri);
            post.setHeader("Accept", "*/*");
            resetHeader(post) ;
            Charset charset = Charset.forName("UTF-8");
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(charset);
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            //加入文件
            builder.addBinaryBody(fileParamName, Base64.getDecoder().decode(base64), ContentType.MULTIPART_FORM_DATA, fileName);
            if(otherText != null){
                Set<Map.Entry<String, Object>> entries = otherText.entrySet();
                ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset);
                for(Map.Entry<String, Object> entrie:entries){
                    builder.addTextBody(entrie.getKey(),entrie.getValue()+"",contentType) ;
                }
            }
            post.setEntity(builder.build());
            log.info("设置文本参数 json={}",JSON.toJSONString(otherText));
            return new Result(mHttp, post);
        }

        /**
         * 文件上传
         * @param fileParamNames
         * @param files
         * @param otherText
         * @return
         */
        public Result postMultipart(String[] fileParamNames,File[] files, Map<String,Object> otherText){
            HttpPost post = new HttpPost(uri);
            int length = files.length;
            if(fileParamNames.length != length){
                throw new IllegalArgumentException("文件参数与文件数量不匹配") ;
            }
            post.setHeader("Accept", "*/*");
            resetHeader(post) ;
            Charset charset = Charset.forName("UTF-8");
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(charset);
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            for(int i =0 ;i<length;i++) {
                //加入文件
                builder.addBinaryBody(fileParamNames[i], files[i], ContentType.MULTIPART_FORM_DATA, files[i].getName());
            }
            if(otherText != null){
                Set<Map.Entry<String, Object>> entries = otherText.entrySet();
                ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset);
                for(Map.Entry<String, Object> entrie:entries){
                    builder.addTextBody(entrie.getKey(),entrie.getValue()+"",contentType) ;
                }
            }
            post.setEntity(builder.build());
            log.info("设置文本参数 json={}",JSON.toJSONString(otherText));
            return new Result(mHttp, post);
        }

        /**
         * get
         * @return
         */
        public Result get() {
            HttpGet rew = new HttpGet(uri);
            resetHeader(rew) ;
            return new Result(mHttp, rew);
        }

        /**
         * 重置头部
         * @param request
         */
        private void resetHeader(HttpUriRequest request){
            Set<Map.Entry<String, String>> entries = header.entrySet();
            for (Map.Entry<String, String> en:entries) {
                request.addHeader(en.getKey(),en.getValue());
            }
        }


    }

    public static class Result {

        private final static Logger log = LoggerFactory.getLogger(HttpClient.class);

        private final static ThreadPoolExecutor pool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                Runtime.getRuntime().availableProcessors() + 2,
                60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(Runtime.getRuntime().availableProcessors() * 2),
                new ThreadPoolExecutor.CallerRunsPolicy());

        private final CloseableHttpClient mHttp;

        private final HttpUriRequest req;

        public Result(CloseableHttpClient mHttp, HttpUriRequest request) {
            this.req = request;
            this.mHttp = mHttp;
        }

        /**
         * 异步执行
         */
        public void async() {
            pool.execute(() -> excute());
        }

        /**
         * 异步执行
         */
        public void async(Consumer<String> consumer) {
            pool.execute(() ->consumer.accept(excute()));
        }

        /**
         * 返回对象
         *
         * @param result
         * @param <T>
         * @return
         */
        public <T> T asObject(Class<T> result) {
            String res = excute();
            if (res != null) {
                return JSON.parseObject(res, result);
            }
            return null;
        }


        /**
         * 无返回执行
         */
        public void excete() {
          excute();
        }

        /**
         * 返回list
         *
         * @param result
         * @param <T>
         * @return
         */
        public <T> List<T> asList(Class<T> result) {
            String res = excute();
            if (res != null) {
                return JSON.parseArray(res, result);
            }
            return null;
        }

        /**
         * 执行
         *
         * @return
         */
        private String excute() {
            CloseableHttpResponse response = null;
            try {
                response = mHttp.execute(req);
                String body = null;
                if (response != null) {
                    body = EntityUtils.toString(response.getEntity(),"UTF-8");
                    if (response.getStatusLine().getStatusCode() != 200) {
                        log.warn("请求{} 异常 {}", req.getURI().toString(), body);
                    } else {
                        log.info("请求{} 成功 {}", req.getURI().toString(), body);
                    }
                }
                return body;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                if (response != null) {
                    try {
                        response.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }

    }


    public static void main(String[] args) throws Exception {
//         文件上传
//        GoFastDto goFast = HttpClient.instance("http://${go-fast.ip}:${go-fast.port}/group1/upload")
//                .postMultipart(new String[]{"file"}, new File[]{newfile}, params)
//                .asObject(GoFastDto.class);
//        Assert.notNull(goFast, "go-fast异常");
        //post请求
//        MtsResponse mtsResponse = HttpClient.instance("${sendRtc.url}/goRtc/api/meetingMgr/finishMeeting")
//                .addHeader("Accept", "*/*")
//                .postJson("{\"meetingId\":" + meetingId + "}")
//                .asObject(MtsResponse.class);
//        Assert.notNull(mtsResponse, "请求mts异常");
//        get请求
//        List<String> configIds = HttpClient.instance(uri+uriSufix).get().asList(String.class);
//        HttpClient.instance("${gosuncn.message.url}/push")
//                .postJson(MessageDto.boxPush(boxHard.getConfigId(), "operate", operate, operate.getSync()))
//                .async((str) -> {
//                    Response response = JSON.parseObject(str, Response.class);
//                    if (response != null && response.isSuccess()) {
//                        uv = 0;
//                        log.info("包厢{}消杀开启成功", boxEntity.getName());
//                    }
//                });
//        HttpClient.instance("${gosuncn.message.url}/push").postJson(dto).excete();
        while (true){
            log.info("========================================================================");
            String json  = "{\"box\":{\"id\":\"HPAQXW44011201\",\"name\":\"锐丰小屋\",\"address\":\"广东省广州市黄埔区锐丰中心(开创大道北)\",\"orgName\":\"萝岗派出所\",\"orgCode\":\"440112012000\",\"point\":\"113.50202237680242,23.172742079906666\",\"photo\":\"/group1/image/图片1.png\"},\"hardware\":[{\"name\":\"接报警终端\",\"configId\":\"2022042110\",\"mac\":\"\",\"type\":\"01\",\"id\":\"c01ddfa9a7c64c98a82a9c19151b8bdf\"},{\"name\":\"门禁控制盒子\",\"configId\":\"2022042111\",\"mac\":\"\",\"type\":\"02\",\"id\":\"db2fe9c3782d4991844bda26a7673cff\"},{\"name\":\"小屋控制主机\",\"configId\":\"2022042111\",\"mac\":\"\",\"type\":\"03\",\"id\":\"64ac7aabf5b847d8b33d83b2df36daaf\"},{\"name\":\"摄像头一\",\"configId\":\"110000000000114\",\"mac\":\"\",\"type\":\"04\",\"id\":\"26c0aefe0f0141e2b6669d9c750f93da\"},{\"name\":\"人脸平板\",\"configId\":\"1\",\"mac\":\"2110980P09801366\",\"type\":\"05\",\"id\":\"13bf9fb2ac8e49ce81f666a50ffefbdf\"},{\"name\":\"摄像头二\",\"configId\":\"110000000000113\",\"mac\":\"\",\"type\":\"06\",\"id\":\"4a9d49363e054bdeb4ffdc507f27a348\"},{\"name\":\"摄像头三\",\"configId\":\"110000000000112\",\"mac\":\"\",\"type\":\"07\",\"id\":\"62596f41bfee4cb48cb474c9f9da97e0\"}]}";
            String json1  = "{\"box\":{\"id\":\"HPAQXW44011204\",\"name\":\"萝岗小屋\",\"address\":\"广东省广州市黄埔区萝岗派出所(香雪大道)\",\"orgName\":\"萝岗派出所\",\"orgCode\":\"440112012000\",\"point\":\"113.48827803212077,23.177311206964188\",\"photo\":\"/group1/image/图片1.png\"},\"hardware\":[{\"name\":\"接报警终端\",\"configId\":\"2022042104\",\"mac\":\"\",\"type\":\"01\",\"id\":\"0f42b1f3ba0b478ca3a956ec499f5232\"},{\"name\":\"门禁控制盒子\",\"configId\":\"2022042105\",\"mac\":\"\",\"type\":\"02\",\"id\":\"e08aafa991d64758b4cf4e3ba0c5a8e1\"},{\"name\":\"小屋控制主机\",\"configId\":\"2022042105\",\"mac\":\"\",\"type\":\"03\",\"id\":\"2a74732e91a140408b0430f15d37bd48\"},{\"name\":\"摄像头一\",\"configId\":\"110000000000028\",\"mac\":\"\",\"type\":\"04\",\"id\":\"cb8f1f71ca6e4ee2abadd08b2415f7a1\"},{\"name\":\"人脸平板\",\"configId\":\"11\",\"mac\":\"2110980P09801367\",\"type\":\"05\",\"id\":\"432e3e4cd8f349ddaf8002c5103382c8\"},{\"name\":\"摄像头二\",\"configId\":\"110000000000029\",\"mac\":\"\",\"type\":\"06\",\"id\":\"d6616821787e4e36b228c55d36a9df13\"},{\"name\":\"摄像头三\",\"configId\":\"110000000000030\",\"mac\":\"\",\"type\":\"07\",\"id\":\"fd0e727f68e2450c93e8e514ae473649\"}]}";
            String json2 = "{\"box\":{\"id\":\"HPAQXW44011205\",\"name\":\"敏捷小屋\",\"address\":\"广东省广州市黄埔区萝岗敏捷广场(水西路北)\",\"orgName\":\"萝岗派出所\",\"orgCode\":\"440112012000\",\"point\":\"113.48237090445241,23.18921015634144\",\"photo\":\"/group1/image/图片1.png\"},\"hardware\":[{\"name\":\"接报警终端\",\"configId\":\"2022042113\",\"mac\":\"\",\"type\":\"01\",\"id\":\"d9454609d46d4e43885dd5e4f3c87f4c\"},{\"name\":\"门禁控制盒子\",\"configId\":\"2022042112\",\"mac\":\"\",\"type\":\"02\",\"id\":\"7d30625598734e7ab7cdad301de1ee1b\"},{\"name\":\"小屋控制主机\",\"configId\":\"2022042112\",\"mac\":\"\",\"type\":\"03\",\"id\":\"4ba221c98fc440d2b242596bdb4f2e8d\"},{\"name\":\"摄像头一\",\"configId\":\"110000000000221\",\"mac\":\"\",\"type\":\"04\",\"id\":\"3446d0b8858b41558f6a95156261c4e1\"},{\"name\":\"人脸平板\",\"configId\":\"123\",\"mac\":\"2130980P09800637\",\"type\":\"05\",\"id\":\"88e92b1c4f1044458a6b952d451a5e0d\"},{\"name\":\"摄像头二\",\"configId\":\"110000000000222\",\"mac\":\"\",\"type\":\"06\",\"id\":\"0e49548f7bc7466e8bb37d64478d6e9d\"},{\"name\":\"摄像头三\",\"configId\":\"110000000000223\",\"mac\":\"\",\"type\":\"07\",\"id\":\"f93a73382fa74179b0147508bc7ef5f4\"}]}";
            String json3 = "{\"box\":{\"id\":\"HPAQXW44011206\",\"name\":\"乐飞小屋\",\"address\":\"广东省广州市黄埔区乐飞家园(开达路西)\",\"orgName\":\"联和派出所\",\"orgCode\":\"440112014000\",\"point\":\"113.48021212181129,23.168497049817812\",\"photo\":\"/group1/image/图片1.png\"},\"hardware\":[{\"name\":\"接报警终端\",\"configId\":\"2022042114\",\"mac\":\"\",\"type\":\"01\",\"id\":\"218efca5e5aa4fbb8432ca98f94353ef\"},{\"name\":\"门禁控制盒子\",\"configId\":\"2022042115\",\"mac\":\"\",\"type\":\"02\",\"id\":\"0fd149d48ca24a7792dc65df1aa2545c\"},{\"name\":\"小屋控制主机\",\"configId\":\"2022042115\",\"mac\":\"\",\"type\":\"03\",\"id\":\"62b75864ed3b47a7ab3e0294f3da5c96\"},{\"name\":\"摄像头一\",\"configId\":\"110000000000133\",\"mac\":\"\",\"type\":\"04\",\"id\":\"3f3d84546f3c4811a2ca3cef4d0a760b\"},{\"name\":\"人脸平板\",\"configId\":\"123\",\"mac\":\"2110980P09801365\",\"type\":\"05\",\"id\":\"42c0a235bf1247d3b6842eabef79826f\"},{\"name\":\"摄像头二\",\"configId\":\"110000000000134\",\"mac\":\"\",\"type\":\"06\",\"id\":\"531a5c2bfae244bcb9c8b01359e15e94\"},{\"name\":\"摄像头三\",\"configId\":\"110000000000135\",\"mac\":\"\",\"type\":\"07\",\"id\":\"ffc5a42ea6d149ca9297bbf4fc9ad269\"}]}";
            String json4 = "{\"box\":{\"id\":\"HPAQXW44011208\",\"name\":\"公路街小屋\",\"address\":\"广东省广州市萝岗荔红小区西南(荔红路)\",\"orgName\":\"萝岗派出所\",\"orgCode\":\"440112012000\",\"point\":\"113.50905584257555,23.175759146386984\",\"photo\":\"/group1/image/图片1.png\"},\"hardware\":[{\"name\":\"接报警终端\",\"configId\":\"2022042107\",\"mac\":\"\",\"type\":\"01\",\"id\":\"f3b193458188413fa503264f54da50f2\"},{\"name\":\"门禁控制盒子\",\"configId\":\"2022042106\",\"mac\":\"\",\"type\":\"02\",\"id\":\"4e1cf188ae9a40ca979ee40a59265727\"},{\"name\":\"小屋控制主机\",\"configId\":\"2022042106\",\"mac\":\"\",\"type\":\"03\",\"id\":\"e7785b6ce8da43c8a461920a6917ff3d\"},{\"name\":\"摄像头一\",\"configId\":\"110000000000206\",\"mac\":\"\",\"type\":\"04\",\"id\":\"5569798c9803430298f4a603fba9bbab\"},{\"name\":\"人脸平板\",\"configId\":\"11\",\"mac\":\"2110980P09801417\",\"type\":\"05\",\"id\":\"d94ea12851b84f9a9d146c1f6de3c531\"},{\"name\":\"摄像头二\",\"configId\":\"110000000000209\",\"mac\":\"\",\"type\":\"06\",\"id\":\"27337f0471684906b4061ba128b819bf\"},{\"name\":\"摄像头三\",\"configId\":\"110000000000210\",\"mac\":\"\",\"type\":\"07\",\"id\":\"defb915658574acd94352ca32744bd25\"}]}";

            String response = HttpClient.instance("http://120.234.192.228:28080/safe/internet/box/updateById")
                    .addHeader("Authorization", "Bearer6b10110f-5e73-4938-9ff2-9f6c45b2125c")
                    .postJson(json)
                    .asObject(String.class);
            String response1 = HttpClient.instance("http://120.234.192.228:28080/safe/internet/box/updateById")
                    .addHeader("Authorization", "Bearer6b10110f-5e73-4938-9ff2-9f6c45b2125c")
                    .postJson(json1)
                    .asObject(String.class);
            String response2 = HttpClient.instance("http://120.234.192.228:28080/safe/internet/box/updateById")
                    .addHeader("Authorization", "Bearer6b10110f-5e73-4938-9ff2-9f6c45b2125c")
                    .postJson(json2)
                    .asObject(String.class);
            String response3 = HttpClient.instance("http://120.234.192.228:28080/safe/internet/box/updateById")
                    .addHeader("Authorization", "Bearer6b10110f-5e73-4938-9ff2-9f6c45b2125c")
                    .postJson(json3)
                    .asObject(String.class);
            String response4 = HttpClient.instance("http://120.234.192.228:28080/safe/internet/box/updateById")
                    .addHeader("Authorization", "Bearer6b10110f-5e73-4938-9ff2-9f6c45b2125c")
                    .postJson(json4)
                    .asObject(String.class);
            log.info("【响应结果】：{}",response);
            log.info("【响应结果】：{}",response1);
            log.info("【响应结果】：{}",response2);
            log.info("【响应结果】：{}",response3);
            log.info("【响应结果】：{}",response4);
            Thread.sleep(1000);
        }
    }

}
